/********* huanxin.m Cordova Plugin Implementation *******/

#import "huanxin.h"
#import "callVideoController.h"

@interface huanxin ()<EMClientDelegate,EMCallManagerDelegate,EMCallManagerDelegate>
@property (strong, nonatomic) EMCallSession *aCallSession;
@property (strong, nonatomic) callVideoController *callVideoVC;
@property (strong, nonatomic) UIViewController *rootVC;


@property (assign, nonatomic) BOOL isCalling;

@property (assign, nonatomic) BOOL isMyEndReason;


@property (copy, nonatomic) NSString *token;
@property (copy, nonatomic) NSString *userid;
@property (copy, nonatomic) NSString *serve_rummingURL;
@property (copy, nonatomic) NSString *serve_endURL;
@property (copy, nonatomic) NSString *cid;

@end
@implementation huanxin
{
    dispatch_source_t timer;
    NSInteger calltime;
}
- (UIViewController *)rootVC
{
    if (!_rootVC) {
        _rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
    }
    return _rootVC;
}

- (void)pluginInitialize
{
    EMOptions *options = [EMOptions optionsWithAppkey:@"minirongyun#huanxin"];
//    options.apnsCertName = @"istore_dev";
    [[EMClient sharedClient] initializeSDKWithOptions:options];

    
    //注册登录相关回调
    [[EMClient sharedClient] addDelegate:self delegateQueue:nil];
    //注册实时通话回调
    [[EMClient sharedClient].callManager addDelegate:self delegateQueue:nil];
 
    
    BOOL isAutoLogin = [EMClient sharedClient].options.isAutoLogin;
    if (isAutoLogin) {
        NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
        NSDictionary * dic = [defaults dictionaryForKey:@"userData"];
        if (dic) {
            self.token = dic[@"token"];
            self.userid = dic[@"userid"];
            self.serve_rummingURL = dic[@"serve_rummingURL"];
            self.serve_endURL = dic[@"serve_endURL"];
        }
        
    }
    NSLog(@"%u==",isAutoLogin);
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        [self startCall];
//    });
    
}

- (void)coolMethod:(CDVInvokedUrlCommand*)command
{
    NSString* echo = [command.arguments objectAtIndex:0];

    if (echo != nil && [echo length] > 0) {
        [self successPluginResult:@{@"success":echo} callbackId:command.callbackId];
    } else {
        [self failurePluginResult:@{@"failure":@""} callbackId:command.callbackId];
    }
}
- (void)successPluginResult:(NSDictionary*) message  callbackId:(NSString*)callbackId
{
    CDVPluginResult* pluginResult = nil;
    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];

}
- (void)failurePluginResult:(NSDictionary*) message  callbackId:(NSString*)callbackId
{
    CDVPluginResult* pluginResult = nil;
    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:message];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
}
- (NSDictionary *)getCommand:(CDVInvokedUrlCommand*)command
{
    if (command.arguments.count == 0) {
        [self failurePluginResult:@{@"error":@"没有d登录数据"} callbackId:command.callbackId];
    }
    return command.arguments[0];
}
//登录
- (void)loginMethod:(CDVInvokedUrlCommand*)command
{
    NSDictionary * dic = [self getCommand:command];
    NSString * userName = dic[@"userName"];
    NSString * password = dic[@"password"];
    self.token = dic[@"token"];
    self.userid = dic[@"userid"];
    self.serve_rummingURL = dic[@"serve_rummingURL"];
    self.serve_endURL = dic[@"serve_endURL"];

    NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:dic forKey:@"userData"];
    
//    self.webViewEngine
    [[EMClient sharedClient] loginWithUsername:userName password:password completion:^(NSString *aUsername, EMError *aError) {
        if (aError) {
            [self failurePluginResult:@{@"error":aError.errorDescription} callbackId:command.callbackId];
        }else{
             [[EMClient sharedClient].options setIsAutoLogin:YES];
            [self successPluginResult:@{@"username":aUsername} callbackId:command.callbackId];
        }
    }];
    NSLog(@"测试一步");
}
//退出
- (void)logoutMethod:(CDVInvokedUrlCommand*)command
{
    [[EMClient sharedClient] logout:YES completion:^(EMError *aError) {
        if (aError) {
            [self failurePluginResult:@{@"error":aError.errorDescription} callbackId:command.callbackId];
        }else{
            [self successPluginResult:@{@"msg":@"已经退出"} callbackId:command.callbackId];
        }
    }];
}

//发起实时通话
- (void)startCallMethod:(CDVInvokedUrlCommand*)command
{
   
    self.isCalling = YES;
    self.isMyEndReason = NO;
    EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions];
    //当对方不在线时，是否给对方发送离线消息和推送，并等待对方回应
    options.isSendPushIfOffline = NO;
    //设置视频分辨率：自适应分辨率、352 * 288、640 * 480、1280 * 720
    options.videoResolution = EMCallVideoResolutionAdaptive;
    //最大视频码率，范围 50 < videoKbps < 5000, 默认0, 0为自适应，建议设置为0
    options.maxVideoKbps = 0;
    //最小视频码率
    options.minVideoKbps = 0;
    //是否固定视频分辨率，默认为NO
    options.isFixedVideoResolution = NO;
    [[EMClient sharedClient].callManager setCallOptions:options];
    
    NSDictionary * dic = [self getCommand:command];
    if (![[dic allKeys] containsObject:@"remoteName"]) {
        [self failurePluginResult:@{@"msg":@"remoteName不能为空"} callbackId:command.callbackId];
        return;
    }
    NSString * remoteName = dic[@"remoteName"];
    NSString * cid = [NSString stringWithFormat:@"%@",dic[@"cid"]];
    self.cid = cid;
    if ([self.cid isEqualToString:@"(null)"]) {
       [self failurePluginResult:@{@"msg":@"没有这个订单号码"} callbackId:command.callbackId];
        return;
    }
    [[EMClient sharedClient].callManager startCall:EMCallTypeVideo remoteName:remoteName ext:self.cid completion:^(EMCallSession *aCallSession, EMError *aError) {
        if (!aError) {
            self.aCallSession = aCallSession;
            [self presenCallVideoVC:1];
            [self successPluginResult:nil callbackId:command.callbackId];
        }else{
            [self failurePluginResult:@{@"msg":aError.errorDescription} callbackId:command.callbackId];

        }
    }];
}

/*!
 *  用户A拨打用户B，用户B会收到这个回调
 *
 *  @param aSession  会话实例
 */
- (void)callDidReceive:(EMCallSession *)aSession
{
    if (!aSession || [aSession.callId length] == 0) {
        return ;
    }
    self.aCallSession = aSession;
    self.cid = [NSString stringWithFormat:@"%@",aSession.ext];
    NSLog(@"-------------2:%@",self.cid);

    if(self.isCalling){
        [[EMClient sharedClient].callManager endCall:aSession.callId reason:EMCallEndReasonBusy];
        return;
    }
    self.isCalling = YES;
    [self presenCallVideoVC:2];
}
//弹出视频页面
- (void)presenCallVideoVC:(NSInteger )type
{
    
    self.callVideoVC = [[callVideoController alloc]init];
    self.callVideoVC.type = type;
    self.callVideoVC.aSession = self.aCallSession;
    [self.rootVC presentViewController:self.callVideoVC animated:YES completion:nil];
    __weak typeof(self) weakSelf = self;
    self.callVideoVC.block = ^(NSInteger num) {
        [weakSelf myAction:num];
    };
}

/*!
 *  通话通道建立完成，用户A和用户B都会收到这个回调
 *
 *  @param aSession  会话实例
 */
- (void)callDidConnect:(EMCallSession *)aSession
{
    self.aCallSession = aSession;
    self.cid = [NSString stringWithFormat:@"%@",aSession.ext];
    NSLog(@"-------------3:%@",self.cid);
    
    EMCallLocalView * LocalView = [[EMCallLocalView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    LocalView.scaleMode = EMCallViewScaleModeAspectFill;
    self.callVideoVC.aSession.localVideoView = LocalView;
    AVAudioSession * audioSession = [AVAudioSession sharedInstance];
    [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
    [audioSession setActive:YES error:nil];
    
}

/*!
 *  用户B同意用户A拨打的通话后，用户A会收到这个回调
 *
 *  @param aSession  会话实例
 */
- (void)callDidAccept:(EMCallSession *)aSession
{
    EMCallRemoteView * RemoteView = [[EMCallRemoteView alloc]initWithFrame:CGRectMake(self.webView.frame.size.width - 130, 90, 120, 190)];
    self.callVideoVC.aSession.remoteVideoView = RemoteView;
    self.callVideoVC.type = 3;
    [self setTime];
}
/*!
 *  1. 用户A或用户B结束通话后，对方会收到该回调
 *  2. 通话出现错误，双方都会收到该回调
 *
 *  @param aSession  会话实例
 *  @param aReason   结束原因
 *  @param aError    错误
 */
- (void)callDidEnd:(EMCallSession *)aSession
            reason:(EMCallEndReason)aReason
             error:(EMError *)aError
{
    self.aCallSession =nil;
    self.isCalling =NO;
    if(timer){
        dispatch_cancel(timer);
        timer =nil;

    }
    [self.callVideoVC dismissViewControllerAnimated:NO completion:^{
        self.callVideoVC = nil;
        NSString * message = @"";
        switch (aReason) {
            case     EMCallEndReasonHangup : {
                if ( self.isMyEndReason ) {
                   message =  @"已挂断";
                }else{
                   message =  @"对方挂断";
                }
            } break;
            case     EMCallEndReasonNoResponse : message =  @"对方没有响应" ; break;
            case     EMCallEndReasonDecline : message =  @"对方拒接" ; break;
            case     EMCallEndReasonBusy : message =  @"对方占线" ; break;
            case     EMCallEndReasonFailed : message =  @"失败" ; break;
            case     EMCallEndReasonUnsupported : message =  @"功能不支持" ; break;
            case     EMCallEndReasonRemoteOffline : message =  @"对方不在线" ; break;
            case     EMCallEndReasonLoginOtherDevice : message =  @"其他设备登录"  ; break;
            case     EMCallEndReasonDestroy : message =  @"通话结束" ; break;
                
            default:
                break;
        }
        [self endCall:message];
        self.isMyEndReason = NO;
    }];
    
}

/*
 *  \~chinese
 *  用户A和用户B正在通话中，用户A的网络状态出现不稳定，用户A会收到该回调
 *
 *  @param aSession  会话实例
 *  @param aStatus   当前状态
*/
- (void)callNetworkDidChange:(EMCallSession *)aSession
                      status:(EMCallNetworkStatus)aStatus
{
    if (aStatus != EMCallNetworkStatusNormal) {
        self.callVideoVC.statusLB.text = @"网络不稳定";
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.callVideoVC.statusLB.text = @"";
        });
    }
}

- (void)autoLoginDidCompleteWithError:(EMError *)aError
{
    if (aError) {
        [self showMessage:@"登录失败..." status:5];
    }else{
        [self showMessage:@"登录成功" status:4];
    }
}
- (void)connectionStateDidChange:(EMConnectionState)aConnectionState
{
    if(aConnectionState == EMConnectionConnected){
        NSLog(@"SDK链接状态:已连接");
        [self showMessage:@"已连接服务器.可以找老师学习咯" status:3];
    }else{
        [self showMessage:@"未连接服务器.正在尝试链接..." status:2];
    }
}

//i应答
- (void)myAction:(NSInteger)num{
    if (num == 1) {//接听
        [[EMClient sharedClient].callManager answerIncomingCall:self.aCallSession.callId];
        self.callVideoVC.type = 3;
        [self setTime];
//        [self successPluginResult:@{@"msg":@"用户同意拨打的通话"} callbackId:self.callDidStart];
    }else if (num == 2) {//拒接
        [[EMClient sharedClient].callManager endCall:self.aCallSession.callId reason:EMCallEndReasonDecline];
//        [self successPluginResult:@{@"msg":@"用户A或用户B结束通话后"} callbackId:self.callDidEnd];
        self.isMyEndReason = YES;
        
    }else if (num == 3) {//挂断
        [[EMClient sharedClient].callManager endCall:self.aCallSession.callId reason:EMCallEndReasonHangup];
         self.isMyEndReason = YES;
//        [self successPluginResult:@{@"msg":@"用户A或用户B结束通话后"} callbackId:self.callDidEnd];

    }
}
- (void)setTime
{
    calltime = 0;
    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        calltime ++ ;
        dispatch_async(dispatch_get_main_queue(), ^{
            self.callVideoVC.timeLB.text = [NSString stringWithFormat:@"%ld",calltime];
        });
       [self notServer];
    });
    dispatch_resume(timer);
}
//视频计时
- (void)notServer{
    
    // 1、创建URL资源地址
    NSURL *url = [NSURL URLWithString:self.serve_rummingURL];
    // 2、创建Reuest请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 3、配置Request
    // 设置请求超时
    [request setTimeoutInterval:30.0];
    // 设置请求方法
    [request setHTTPMethod:@"POST"];
    // 4、构造请求参数
    // 4.1、创建字典参数，将参数放入字典中，可防止程序员在主观意识上犯错误，即参数写错。
    NSDictionary *parametersDict = @{@"token":self.token,@"userid":self.userid,@"cid":self.cid};
    NSLog(@"-------------1:%@",parametersDict);
    // 4.2、遍历字典，以“key=value&”的方式创建参数字符串。
    NSMutableString *parameterString = [[NSMutableString alloc]init];
    int pos =0;
    for (NSString *key in parametersDict.allKeys) {
        // 拼接字符串
        [parameterString appendFormat:@"%@=%@", key, parametersDict[key]];
        if(pos<parametersDict.allKeys.count-1){
            [parameterString appendString:@"&"];
        }
        pos++;
    }
    // 4.3、NSString转成NSData数据类型。
    NSData *parametersData = [parameterString dataUsingEncoding:NSUTF8StringEncoding];
    // 5、设置请求报文
    [request setHTTPBody:parametersData];
    // 6、构造NSURLSessionConfiguration
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    // 7、创建网络会话
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
    // 8、创建会话任务
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // 10、判断是否请求成功
        if (error) {
            NSLog(@"post error :%@",error.localizedDescription);
        }else {
            // 如果请求成功，则解析数据。
            id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
            // 11、判断是否解析成功
            if (error) {
                NSLog(@"post error :%@",error.localizedDescription);
            }else {
                // 解析成功，处理数据，通过GCD获取主队列，在主线程中刷新界面。
                NSLog(@"post success :%@",object);
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    if([[NSString stringWithFormat:@"%@",object[@"code"]] isEqualToString:@"200"] && ([[NSString stringWithFormat:@"%@",object[@"data"][@"status"]] isEqualToString:@"0"] || [[NSString stringWithFormat:@"%@",object[@"data"][@"status"]] isEqualToString:@"1"])){
                        
                    }else
                    {
                        [self myAction:3];
                    }
                });
                
            }
        }
        
    }];
    // 9、执行任务
    [task resume];
    
}

//结束视频后通知webview
- (void)endCall:(NSString *)message
{
    [self showMessage:message status:1];
    
    // 1、创建URL资源地址
    NSURL *url = [NSURL URLWithString:self.serve_endURL];
    // 2、创建Reuest请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 3、配置Request
    // 设置请求超时
    [request setTimeoutInterval:30.0];
    // 设置请求方法
    [request setHTTPMethod:@"POST"];
    // 4、构造请求参数
    // 4.1、创建字典参数，将参数放入字典中，可防止程序员在主观意识上犯错误，即参数写错。
    NSDictionary *parametersDict = @{@"token":self.token,@"userid":self.userid,@"cid":self.cid};
    NSLog(@"-------------1:%@",parametersDict);
    // 4.2、遍历字典，以“key=value&”的方式创建参数字符串。
    NSMutableString *parameterString = [[NSMutableString alloc]init];
    int pos =0;
    for (NSString *key in parametersDict.allKeys) {
        // 拼接字符串
        [parameterString appendFormat:@"%@=%@", key, parametersDict[key]];
        if(pos<parametersDict.allKeys.count-1){
            [parameterString appendString:@"&"];
        }
        pos++;
    }
    // 4.3、NSString转成NSData数据类型。
    NSData *parametersData = [parameterString dataUsingEncoding:NSUTF8StringEncoding];
    // 5、设置请求报文
    [request setHTTPBody:parametersData];
    // 6、构造NSURLSessionConfiguration
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    // 7、创建网络会话
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
    // 8、创建会话任务
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // 10、判断是否请求成功
        if (error) {
            NSLog(@"post error :%@",error.localizedDescription);
        }else {
            // 如果请求成功，则解析数据。
            id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
            // 11、判断是否解析成功
            if (error) {
                NSLog(@"post error :%@",error.localizedDescription);
            }else {
                // 解析成功，处理数据，通过GCD获取主队列，在主线程中刷新界面。
                NSLog(@"post success :%@",object);
                
//                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//                    if([[NSString stringWithFormat:@"%@",object[@"code"]] isEqualToString:@"200"] && ([[NSString stringWithFormat:@"%@",object[@"data"][@"status"]] isEqualToString:@"0"] || [[NSString stringWithFormat:@"%@",object[@"data"][@"status"]] isEqualToString:@"1"])){
//
//                    }else
//                    {
//                        [self myAction:3];
//                    }
//                });
                
            }
        }
        
    }];
    // 9、执行任务
    [task resume];
    
}
//status 
//1挂断
//2未连接服务器.正在尝试链接...
//3已连接服务器.可以找老师学习咯
//4登录成功
//5登录失败...

- (void)showMessage:(NSString *)message status:(NSInteger)status
{
    NSDictionary * dic = @{
        @"message":message,
        @"status":@(status)
    };
    
    if (@available(iOS 11.0, *)) {
        NSData * data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingSortedKeys error:nil];
        NSString * string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSString * JS = [NSString stringWithFormat:@"IM.callend('%@');",string];
        [self evaluateJS:JS];
    } else {
        NSString * JS = [NSString stringWithFormat:@"IM.callend('%@');",message];
        [self evaluateJS:JS];
    }

}
- (void)evaluateJS:(NSString *)JS{
    [self.commandDelegate evalJs:JS];
}


@end
